package tq.liandu;

import android.util.Log;

import java.security.MessageDigest;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * Created by Administrator on 2017/9/23.
 */
//des和aes加密标准很多种容易出现结果不一样的时候
public  class Sherlock{

    public  static Sherlock  mSherlock;
    private  byte[]  msrc ;

    private byte[]  dest ;

    private String  destString=null;

    private String  type=null;
    private  int    skill=0;
    public   String  mworld="PC";

    private  void  echo(String str){

        if(mworld.equals("PC")){

            System.out.println(str);
        }else if(mworld.equals("ANDROID")){
            Log.i("sherlock",str);
        }


    }
    private  void  echo(int str){

        echo(str+"");
    }

    public  void setWorld(String world){
        if(world.equals("PC")){
            mworld="PC";
        }else if(world.equals("ANDROID")){

            mworld="ANDROID";
        }else{
            echo("sorrry no this set");
        }


    }

    public static Sherlock SummonSherlock(){

        if(mSherlock == null){

            mSherlock = new Sherlock();
        }

        return  mSherlock;
    }

    public  Sherlock type(String  type){


        this.type= type;
        if(this.type.length() == 0 || this.type == null){

            echo ("sorry you must give a explicit  type like  MD5 or  AES");
            return null;
        }

        if(type.equals("MD5")){

            skill =1;
        }else if(type.equals("SHA1")){

            skill =2;
        }else if(type.equals("DES")){

            skill =3;
        }else if(type.equals("AES")){

            skill =4;
        }else {

            skill=0;
        }

        echo("skill is "+skill);
        return this;

    }
    public Sherlock  working (String  src){

        return  working(src,null);
    }
    public Sherlock  working(String src, String passwd){


        switch(skill) {

            case 1:

                MD5Sum(src);
                break;

            case 2:
                SHA1Sum(src);
                break;

            case 3:

                DESEncrypt(src.getBytes(), passwd);
                break;

            case 4:
                AESEncrypt(src, passwd);
                break;

            default:


        }
        return this;

    }
    //////////////SHA1
    public void  SHA1Sum(String str){
        if (null == str || 0 == str.length()){

        }
        char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f'};
        try {
            MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
            mdTemp.update(str.getBytes("UTF-8"));

            byte[] md = mdTemp.digest();
            int j = md.length;
            char[] buf = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
                buf[k++] = hexDigits[byte0 & 0xf];
            }

           destString =new String(buf);

        } catch (Exception e) {
            e.printStackTrace();

        }


    }


    ///////////////MD5
    public  void  MD5Sum(String  input){

        MessageDigest md5Obj = null;

        try
        {
            md5Obj = MessageDigest.getInstance("MD5");
        }
        catch (Exception e)
        {
            System.out.println("Hash Algorithm not supported");
            System.exit(-1);
        }
        byte[] hashBytes = new byte[40];
        md5Obj.update(input.getBytes(), 0, input.length());
        hashBytes = md5Obj.digest();
        dest = hashBytes;
        //System.out.println(byteArrayToHexString(hashBytes));
            /*     MessageDigest md5 =MessageDigest.getInstance("MD5");
        String  a=new String (byteArrayToHexString(md5.digest("123456".getBytes())));
        System.out.println(a);*/


    }

    public  String  getResult(){


        return enCryptString();
    }
    ////////////////////////////////////////////transer
    private  byte[] hexStringToByteArray(String s)
    {
//这个一般是加密后的解密的时候甩的  直接加密就用String.togetarray()
        System.out.print(s);
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[(i / 2)] =
                    ((byte)((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16)));
        }
        return data;
    }


    private  String byteArrayToHexString(byte[] data)
    {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < data.length; i++)
        {
            int halfbyte = data[i] >>> 4 & 0xF;
            int two_halfs = 0;
            do
            {
                if ((halfbyte >= 0) && (halfbyte <= 9)) {
                    buf.append((char)(48 + halfbyte));
                } else {
                    buf.append((char)(97 + (halfbyte - 10)));
                }
                halfbyte = data[i] & 0xF;
            } while (

                    two_halfs++ < 1);
        }
        return buf.toString();
    }

    private  byte[]  transToByte(String  tran){

        return hexStringToByteArray(tran);
    }

   public   String  enCryptString(){


        if(skill == 1 || skill == 3 || skill == 4){

            return byteArrayToHexString(dest);

        }else if(skill ==2){

            return destString;
        }
            return null;
    }


    public void  DESDecrypt(byte[] crypt, String password)  {
// DES算法要求有一个可信任的随机数源

        try {
            SecureRandom random = new SecureRandom();
// 创建一个DESKeySpec对象
            DESKeySpec desKey = new DESKeySpec(password.getBytes());
// 创建一个密匙工厂
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// 将DESKeySpec对象转换成SecretKey对象
            SecretKey securekey = keyFactory.generateSecret(desKey);
// Cipher对象实际完成解密操作
            Cipher cipher = Cipher.getInstance("DES");
// 用密匙初始化Cipher对象
            cipher.init(Cipher.DECRYPT_MODE, securekey, random);
// 真正开始解密操作
            dest = cipher.doFinal(crypt);
        }catch (Exception e){

            e.printStackTrace();
        }

    }
    public void  DESEncrypt(byte[] datasource, String password) {

       echo("this is DES   encrypt");
        try{
            SecureRandom random = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec(password.getBytes());
//创建一个密匙工厂，然后用它把DESKeySpec转换成
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey securekey = keyFactory.generateSecret(desKey);
//Cipher对象实际完成加密操作
            Cipher cipher = Cipher.getInstance("DES");
//用密匙初始化Cipher对象
            cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
//现在，获取数据并加密
//正式执行加密操作
           // echo(new String(cipher.doFinal(datasource)));
            echo(byteArrayToHexString(cipher.doFinal(datasource)));
            dest = cipher.doFinal(datasource);
        }catch(Throwable e){
            e.printStackTrace();
        }

    }

    public void   AESDecrypt(byte[] content, String password) {
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, new SecureRandom(password.getBytes()));
            SecretKey secretKey = kgen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance("AES");// 创建密码器
            cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
            byte[] result = cipher.doFinal(content);

            dest=result;
            //return result; // 加密
        } catch (Exception e) {
            e.printStackTrace();

        }

    }
    public  void  AESEncrypt(String content, String password) {
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            kgen.init(128, new SecureRandom(password.getBytes()));
            SecretKey secretKey = kgen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance("AES");// 创建密码器
            byte[] byteContent = content.getBytes("utf-8");
            cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
            byte[] result = cipher.doFinal(byteContent);

            dest=result;

           // echo(byteArrayToHexString(result));
        } catch (Exception e) {
            e.printStackTrace();

        }

    }



}
